/* Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of NVIDIA CORPORATION nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <auxdata.h>

#ifndef _WIN32
#include <cxxabi.h>
const std::string type_demangle(const char *name)
{
    int status = -4;
    char *res = abi::__cxa_demangle(name, NULL, NULL, &status);
    const char *const demangled_name = (status == 0) ? res : name;
    std::string ret_val(demangled_name);
    free(res);
    return ret_val;
}
#else
const std::string type_demangle(const char *name)
{
    return std::string(name);
}
#endif

namespace amgx
{

void AuxDB::printExistingData() const
{
    printf("Storing parameters with names:\n");
    ParamPtrDB::const_iterator iter;

    for (iter = ptrparams.begin(); iter != ptrparams.end(); ++iter)
    {
        printf("%s\n", iter->first.c_str());
    }

    ParamDB::const_iterator iter2;

    for (iter2 = params.begin(); iter2 != params.end(); ++iter2)
    {
        printf("%s\n", iter2->first.c_str());
    }
}

bool AuxDB::hasParameter(const std::string &name) const
{
    return (params.find(name) != params.end() || ptrparams.find(name) != ptrparams.end());
}

void AuxDB::copyParameters(const AuxDB *src)
{
    // clear existing pointers?
    clearPtrs();
    params = src->params;
    ParamPtrDB::const_iterator iter;

    for (iter = src->ptrparams.begin(); iter != src->ptrparams.end(); ++iter)
    {
        AuxPtr<int> *item = new AuxPtr<int>((int *)(iter->second->Get()), false); // specify some type instead of void to avoid "delete void*" warning. This object won't delete this pointed object.
        item->force_typename(iter->second->type_name);
        ptrparams[iter->first] = item;
    }
}

void AuxDB::clearPtrs()
{
    ParamPtrDB::const_iterator iter;

    for (iter = ptrparams.begin(); iter != ptrparams.end(); ++iter)
    {
        delete iter->second;
    }

    ptrparams.clear();
}

AuxDB::~AuxDB()
{
    clearPtrs();
}

} // namespace amgx
